<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Canvas</title>
  </head>
  <body>
    <canvas width="200" height="200" id="canvas"></canvas>

    <img alt="图片" id="image" />

    <script>
      const image = document.getElementById('image');
      /** @type {HTMLCanvasElement} */
      const canvas = document.getElementById('canvas');
      const drawing = document.getElementById('canvas');
      const context = canvas.getContext('2d');
      const gl = canvas.getContext('webgl', { alpha: false });

      baseGl();

      function baseDraw() {
        // 绘制红色矩形
        context.fillStyle = '#ff0000';
        context.fillRect(10, 10, 50, 50);
        // 绘制半透明蓝色矩形
        context.fillStyle = 'rgba(0,0,255,0.5)';
        context.fillRect(30, 30, 50, 50);
        // 在前两个矩形重叠的区域擦除一个矩形区域
        context.clearRect(40, 40, 10, 10);

        // 创建路径
        context.beginPath();
        // 绘制外圆
        context.arc(100, 100, 99, 0, 2 * Math.PI, false);
        // 绘制内圆
        context.moveTo(194, 100);
        context.arc(100, 100, 94, 0, 2 * Math.PI, false);
        // // 绘制分针
        // context.moveTo(100, 100);
        // context.lineTo(100, 15);
        // // 绘制时针
        // context.moveTo(100, 100);
        // context.lineTo(35, 100);
        // 移动原点到表盘中心
        context.translate(100, 100);
        context.rotate(1);
        // 绘制分针
        context.moveTo(0, 0);
        context.lineTo(0, -85);
        // 绘制时针
        context.moveTo(0, 0);
        context.lineTo(-65, 0);
        // 描画路径
        context.stroke();

        context.rotate(-1);
        context.translate(-100, -100);

        // 正常
        context.font = 'bold 14px Arial';
        context.textAlign = 'center';
        context.textBaseline = 'middle';
        context.fillText('12', 100, 20);
        // 与开头对齐
        context.textAlign = 'start';
        context.fillText('12', 100, 40);
        // 与末尾对齐
        context.textAlign = 'end';
        context.fillText('12', 100, 60);

        let fontSize = 100;
        context.font = fontSize + 'px Arial';
        context.textAlign = 'center';
        while (context.measureText('Hello world!').width > 100) {
          fontSize--;
          context.font = fontSize + 'px Arial';
        }
        context.fillText('Hello world!', 100, 10);
        context.fillText('Font size is ' + fontSize + 'px', 100, 50);

        image.src = canvas.toDataURL('image/png');

        let bg = new Image();
        bg.src = './18023.jpg';
        bg.onload = function () {
          context.drawImage(bg, 0, 0);
          // 要绘制的图像、源图像x 坐标、源图像y 坐标、源图像宽度、源图像高度、目标区域x 坐标、目标区域y 坐标、目标区域宽度和目标区域高度。
          context.drawImage(bg, 1000, 1000, 100, 100, 50, 50, 100, 100);
          context.drawImage(bg, 100, 100, 20, 13);
        };
      }

      function createRectLinearGradient(context, x, y, width, height) {
        return context.createLinearGradient(x, y, x + width, y + height);
      }

      function shadowDraw() {
        // 设置阴影
        context.shadowOffsetX = 5;
        context.shadowOffsetY = 5;
        context.shadowBlur = 4;
        context.shadowColor = 'rgba(0, 0, 0, 0.5)';
        // 绘制红色矩形
        context.fillStyle = '#ff0000';
        context.fillRect(10, 10, 50, 50);
        // 在画布上从(30, 30)到(70, 70)绘制一个渐变
        let gradient = context.createLinearGradient(30, 30, 70, 70);
        gradient = createRectLinearGradient(context, 30, 30, 50, 50);
        gradient = context.createRadialGradient(55, 55, 10, 55, 55, 30);
        gradient.addColorStop(0, 'red');
        gradient.addColorStop(0.5, 'green');
        gradient.addColorStop(1, 'yellow');
        // 绘制蓝色矩形
        // context.fillStyle = 'rgba(0, 0, 255, 1)';
        context.fillStyle = gradient;
        context.fillRect(30, 30, 50, 50);
      }

      function imgDraw() {
        let bg = new Image();
        bg.src = './18023.jpg';
        bg.onload = function () {
          context.drawImage(bg, 1000, 1000, 100, 100, 50, 50, 100, 100);

          // 取得图像数据
          let imageData = context.getImageData(50, 50, 100, 100);
          let data = imageData.data;
          for (i = 0, len = data.length; i < len; i += 4) {
            red = data[i];
            green = data[i + 1];
            blue = data[i + 2];
            alpha = data[i + 3];
            // 取得RGB 平均值
            average = Math.floor((red + green + blue) / 3);
            // 设置颜色，不管透明度
            data[i] = average;
            data[i + 1] = average;
            data[i + 2] = average;
          }
          // 将修改后的数据写回ImageData 并应用到画布上显示出来
          imageData.data = data;
          context.putImageData(imageData, 50, 50);
        };
      }

      function compositeDraw() {
        // 绘制红色矩形
        context.fillStyle = '#ff0000';
        context.fillRect(10, 10, 50, 50);
        // 设置合成方式
        //  source-over：默认值，新图形绘制在原有图形上面。
        //  source-in：新图形只绘制出与原有图形重叠的部分，画布上其余部分全部透明。
        //  source-out：新图形只绘制出不与原有图形重叠的部分，画布上其余部分全部透明。
        //  source-atop：新图形只绘制出与原有图形重叠的部分，原有图形不受影响。
        //  destination-over：新图形绘制在原有图形下面，重叠部分只有原图形透明像素下的部分可见。
        //  destination-in：新图形绘制在原有图形下面，画布上只剩下二者重叠的部分，其余部分完全透明。
        //  destination-out：新图形与原有图形重叠的部分完全透明，原图形其余部分不受影响。
        //  destination-atop：新图形绘制在原有图形下面，原有图形与新图形不重叠的部分完全透明。
        //  lighter：新图形与原有图形重叠部分的像素值相加，使该部分变亮。
        //  copy：新图形将擦除并完全取代原有图形。
        //  xor：新图形与原有图形重叠部分的像素执行“异或”计算
        context.globalCompositeOperation = 'destination-over';
        context.globalCompositeOperation = 'source-atop';
        context.globalCompositeOperation = 'lighter';
        context.globalCompositeOperation = 'copy';
        context.globalCompositeOperation = 'xor';
        // 绘制蓝色矩形
        context.fillStyle = 'rgba(0,0,255,1)';
        context.fillRect(30, 30, 50, 50);
      }

      function baseGl() {
        if (gl) {
          //
        }
      }
    </script>
  </body>
</html>
